package cn.hw.server.controller;

import cn.hw.server.entity.Application;
import cn.hw.server.entity.User;
import cn.hw.server.service.ApplicationService;
import cn.hw.server.service.UserService;
import cn.hw.server.util.*;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
@Slf4j
public class SSOServerController {

    @Autowired
    private UserService userService;

    @Autowired
    private ApplicationService applicationService;


    @PostMapping("/login")
    public String login(
            @RequestParam String loginName,
            @RequestParam String redirectUrl,
            @RequestParam String loginPassword,
            @RequestParam String verifyImg,
            HttpSession session) {
        String oldToken = (String) session.getAttribute("token");
        Object info = RedisUtil.get(oldToken);
        if (!StringUtils.isEmpty(oldToken) && info != null) {
            return "redirect:" + redirectUrl + "?token=" + oldToken;
        }
        if (verifyImg.equals(session.getAttribute("verifyCode"))) {
            User byLoginName = userService.findByLoginName(loginName);
            if (byLoginName != null && byLoginName.getLoginPassword().equals(DigestUtils.md5DigestAsHex((loginName + loginPassword).getBytes()))) {
                log.info("认证通过");
                String token = UUIDUtil.getUUID8();
                session.setAttribute("token", token);
                TokenInfo tokenInfo = new TokenInfo();
                tokenInfo.setUser(byLoginName);
                RedisUtil.put(token, tokenInfo, 10800, TimeUnit.SECONDS);
                return "redirect:" + redirectUrl + "?token=" + token;
            }
        }


        return "redirect:login.html?redirectUrl=" + redirectUrl;
    }

    @PostMapping("/verify")
    @ResponseBody
    public ReturnBean verify(String token, String name, String jsessionid) throws Exception {
        TokenInfo tokenInfo = RedisUtil.get(token);
        if (tokenInfo != null) {
            List<Application> applications = tokenInfo.getApplications();
            Application application = applicationService.findByName(name);
            if (application == null) {
                return ReturnBean.of(ReturnBean.AnswerCode.APPLICATION_NOT_EXIST, "客户端连接不存在请联系管理员");
            }
            application.setJsessionid(jsessionid);
            log.info("{}登录系统", application);
            applications.add(application);
            RedisUtil.put(token, tokenInfo, 10800, TimeUnit.SECONDS);
            JSONObject header = new JSONObject();
            header.put("Cookie", "JSESSIONID=" + jsessionid);
            JSONObject data = new JSONObject();
            data.put("userInfo", JacksonUtil.toJsonString(tokenInfo.getUser()));
            data.put("name", application.getName());
            System.out.println(data);
            RpcUtil.httpInvoke(application.getClientUrl() + "/login", data, header, HttpMethod.POST, false, String.class);
            return ReturnBean.of(ReturnBean.AnswerCode.SUCCESS);
        } else {
            return ReturnBean.of(ReturnBean.AnswerCode.AUTH_TIMEOUT);
        }
    }

    @GetMapping("/verifyImg")
    @ResponseBody
    public void verifyImg(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setDateHeader("Expire", 0);
        VerifyUtil randomValidateCode = new VerifyUtil();
        randomValidateCode.getRandcode(request, response);
    }


    @GetMapping({"/logOut"})
    public String logOut(HttpSession session, HttpServletRequest request) {
        String referer = request.getHeader("Referer");
        String[] split = referer.split("\\?");
        String token = (String) session.getAttribute("token");
        if (!StringUtils.isEmpty(token)) {
            TokenInfo tokenInfo = RedisUtil.get(token);
            if (tokenInfo != null) {
                User user = tokenInfo.getUser();
                List<Application> applications = tokenInfo.getApplications();
                log.info("退出系统{}", user);
                for (Application application : applications) {
                    if (application == null) {
                        continue;
                    }
                    log.info("退出系统{}", application);
                    JSONObject header = new JSONObject();
                    header.put("Cookie", "JSESSIONID=" + application.getJsessionid());
                    RpcUtil.httpInvoke(application.getClientUrl() + "/logOut", null, header, HttpMethod.GET, false, String.class);
                }
            }
        }
        RedisUtil.delete(token);
        //清除session
        session.invalidate();

        return "redirect:login.html?redirectUrl=" + split[0];
    }


}
